﻿using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using System.Xml;
using System.Data;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Collections;
using System.ComponentModel;

namespace CAML2HTML.Controls
{
    [Guid("b6eafec8-7b45-4861-8960-db9b874fbdb0")]
    public class CAML2HTMLWebPart : System.Web.UI.WebControls.WebParts.WebPart
    {
        public CAML2HTMLWebPart(): base()
        {
            this.ExportMode = WebPartExportMode.All;
            pfassembly = System.Reflection.Assembly.GetExecutingAssembly();
            ppassembly = System.Reflection.Assembly.GetExecutingAssembly();
        }

        private System.Xml.Xsl.XslTransform xsldoc = new System.Xml.Xsl.XslTransform();
        private System.Xml.XmlDocument camldoc = new System.Xml.XmlDocument();
        private System.Xml.XmlDocument xmldoc = new System.Xml.XmlDocument();
        private System.Xml.XmlDocument extraxmldoc = new System.Xml.XmlDocument();
        private DataSet dsResults = new DataSet();
        private System.Xml.XmlDocument xmlres = new XmlDocument();

        private bool debug = false;
        [WebBrowsable(true),
         Personalizable(true),
         Category("Query"),
         DisplayName("Debug"),
         WebDisplayName("Debug"),
         Description("Show some debug information.")]
        public bool Debug
        {
            get { return debug; }
            set { debug = value; }
        }

        private string website = "";
        [WebBrowsable(true),
         Personalizable(true),
         Category("Query"),
         DisplayName("Site"),
         WebDisplayName("Site"),
         Description("Please enter the URL of the Site where you want to run the query. Cannot be used alongside the List parameter.")]
        public string Website
        {
            get { return website; }
            set { website = value; }
        }

        private string camlfile = "";
        [WebBrowsable(true),
         Personalizable(true),
         Category("Query"),
         DisplayName("CAML Query (file)"),
         WebDisplayName("CAML Query (file)"),
         Description("Please enter the URL of the CAML Query you want to issue to the Site specified.")]
        public string Camlfile
        {
            get { return camlfile; }
            set {
                try
                {
                    camlfile = value;
                    if (camlfile != "")
                    {
                        LoadCAML(camlfile);
                    }
                }
                catch (Exception e)
                {
                    //camlfile = "";
                    throw (e);
                }
            }
        }

        private string caml = "";
        [WebBrowsable(true),
         Personalizable(true),
         Category("Query"),
         DisplayName("CAML Query (plain text)"),
         WebDisplayName("CAML Query (plain text)"),
         Description("Please enter the CAML Query you want to issue to the Site specified.")]
        public string Caml
        {
            get { return caml; }
            set {
                try
                {
                    caml = value;
                    if (caml != "")
                    {
                        XmlReader tempxml = XmlReader.Create(new System.IO.StringReader(caml));
                        camldoc.Load(tempxml);
                        tempxml.Close();
                        tempxml = null;
                    }
                }
                catch (Exception e)
                {
                    caml = "";
                    throw (e);
                }
            }
        }

        public enum listproperties
        {
            None, SomeProperties, FullProperties, Schema
        }
        private listproperties getlistprop = listproperties.None;
        [WebBrowsable(true),
         Personalizable(true),
         Category("Query"),
         DisplayName("Get List Properties"),
         WebDisplayName("Get List Properties"),
         Description("Get the list properties or xml schema for CAML queries that request information from only one list at a time.")]
        public listproperties GetListProp
        {
            get { return getlistprop; }
            set { getlistprop = value; }
        }

        private bool passparameters = false;
        [WebBrowsable(true),
         Personalizable(true),
         Category("Query"),
         DisplayName("Pass Query Parameters"),
         WebDisplayName("Pass Query Parameters"),
         Description("Pass the Query Parameters to the XSL Style Sheet storing them in ExtraXML structure.")]
        public bool PassParameters
        {
            get { return passparameters; }
            set { passparameters = value; }
        }

        private string xmlfile = "";
        [WebBrowsable(true),
         Personalizable(true),
         Category("Custom XML"),
         DisplayName("XML Document (file)"),
         WebDisplayName("XML Document (file)"),
         Description("Please enter the URL of the custom XML document you want to render.")]
        public string Xmlfile
        {
            get { return xmlfile; }
            set
            {
                try
                {
                    xmlfile = value;
                    if (xmlfile != "")
                    {
                        xmldoc.Load(LoadXML(xmlfile));
                    }
                }
                catch (Exception e)
                {
                    //xmlfile = "";
                    throw (e);
                }
            }
        }

        private string xmlstring = "";
        [WebBrowsable(true),
         Personalizable(true),
         Category("Custom XML"),
         DisplayName("XML Document (plain text)"),
         WebDisplayName("XML Document (plain text)"),
         Description("Please enter the custom XML document you want to render.")]
        public string Xmlstring
        {
            get { return xmlstring; }
            set
            {
                try
                {
                    xmlstring = value;
                    if (xmlstring != "")
                    {
                        XmlReader tempxml = XmlReader.Create(new System.IO.StringReader(xmlstring));
                        xmldoc.Load(tempxml);
                        tempxml.Close();
                        tempxml = null;
                    }
                }
                catch (Exception e)
                {
                    xmlstring = "";
                    throw (e);
                }
            }
        }

        private string xslfile = "";
        [WebBrowsable(true),
         Personalizable(true),
         Category("Render"),
         DisplayName("XSL Sheet (file)"),
         WebDisplayName("XSL Sheet (file)"),
         Description("Please enter the URL of the XSL Sheet used to transformate the XML resultant of the CAML query into HTML. If you specify this parameter don't use the next one.")]
        public string Xslfile
        {
            get { return xslfile; }
            set {
                try
                {
                    xslfile = value;
                    if (xslfile != "")
                    {
                        LoadXSL(xslfile);
                    }
                }
                catch (Exception e)
                {
                    //xslfile = "";
                    throw (e);
                }
            }
        }

        private string xsl = "";
        [WebBrowsable(true),
         Personalizable(true),
         Category("Render"),
         DisplayName("XSL Sheet (plain text)"),
         WebDisplayName("XSL Sheet (plain text)"),
         Description("Please enter the XSL Sheet used to transformate the XML resultant of the CAML query into HTML. Don't use this parameter if you already specified the previous one.")]
        public string Xsl
        {
            get { return xsl; }
            set {
                try
                {
                    xsl = value;
                    if (xsl != "") 
                    {
                        XmlReader tempxml = XmlReader.Create(new System.IO.StringReader(xsl));
                        xsldoc.Load(tempxml);
                        tempxml.Close();
                        tempxml = null;
                    }
                }
                catch (Exception e)
                {
                    xsl = "";
                    throw (e);
                }
            }
        }

        private string preprocessassmebly = "";
        private System.Reflection.Assembly ppassembly;
        [WebBrowsable(true),
         Personalizable(true),
         Category("Pre-Process"),
         DisplayName("Pre-Process Assembly"),
         WebDisplayName("Pre-Process Assembly"),
         Description("Please enter the location of the Assembly with one or more clases that implements the IPreProcess interface to process the input parameters to build de CAML query. The location could be a full path or the strong name of the assembly. Leave it blank if you want to use the built-in PreProcess Classes.")]
        public string PreProcessAssembly
        {
            get { return preprocessassmebly; }
            set
            {
                try
                {
                    preprocessassmebly = value;
                    if (preprocessassmebly != "")
                    {
                        ppassembly = CargarAssembly(preprocessassmebly);
                    }
                }
                catch (Exception e)
                {
                    //preprocessassmebly = "";
                    throw (e);
                }
            }
        }

        private string preprocessclass = "";
        private System.Type pptype;
        private Interfaces.IPreProcess[] ppclass;
        [WebBrowsable(true),
         Personalizable(true),
         Category("Pre-Process"),
         DisplayName("Pre-Process Classes"),
         WebDisplayName("Pre-Process Classes"),
         Description("Please enter the ClassName of the Classes (separated by comma) in the PreProcess Assembly who implements the IPreProcess interface that will be used to process the input parameters before issuing the CAML query. The Classes will be invoked in the order of appearence.")]
        public string PreProcessClass
        {
            get { return preprocessclass; }
            set
            {
                try
                {
                    preprocessclass = value;
                }
                catch (Exception e)
                {
                    //preprocessclass = "";
                    throw (e);
                }
            }
        }

        private string preprocessparam1 = "";
        [WebBrowsable(true),
         Personalizable(true),
         Category("Pre-Process"),
         DisplayName("Custom Parameter 1"),
         WebDisplayName("Custom Parameter 1"),
         Description("Please enter the value of Parameter 1 passed to Pre-Process class.")]
        public string PreProcessParam1
        {
            get { return preprocessparam1; }
            set { preprocessparam1 = value; }
        }

        private string preprocessparam2 = "";
        [WebBrowsable(true),
         Personalizable(true),
         Category("Pre-Process"),
         DisplayName("Custom Parameter 2"),
         WebDisplayName("Custom Parameter 2"),
         Description("Please enter the value of Parameter 2 passed to Pre-Process class.")]
        public string PreProcessParam2
        {
            get { return preprocessparam2; }
            set { preprocessparam2 = value; }
        }

        private string preprocessparam3 = "";
        [WebBrowsable(true),
         Personalizable(true),
         Category("Pre-Process"),
         DisplayName("Custom Parameter 3"),
         WebDisplayName("Custom Parameter 3"),
         Description("Please enter the value of Parameter 3 passed to Pre-Process class.")]
        public string PreProcessParam3
        {
            get { return preprocessparam3; }
            set { preprocessparam3 = value; }
        }

        private string preprocessparam4 = "";
        [WebBrowsable(true),
         Personalizable(true),
         Category("Pre-Process"),
         DisplayName("Custom Parameter 4"),
         WebDisplayName("Custom Parameter 4"),
         Description("Please enter the value of Parameter 4 passed to Pre-Process class.")]
        public string PreProcessParam4
        {
            get { return preprocessparam4; }
            set { preprocessparam4 = value; }
        }

        private string postfilterassmebly = "";
        private System.Reflection.Assembly pfassembly;
        [WebBrowsable(true),
         Personalizable(true),
         Category("Post Filter"),
         DisplayName("Post Filter Assembly"),
         WebDisplayName("Post Filter Assembly"),
         Description("Please enter the location of the Assembly with one or more clases that implements the IPostFilter interface to process the XML resultant of the CAML query before parsing it with the XSLT Stylesheet. The location could be a full path or the strong name of the assembly. Leave it blank if you want to use the built-in PostFilter Classes.")]
        public string PostFilterAssembly
        {
            get { return postfilterassmebly; }
            set
            {
                try
                {
                    postfilterassmebly = value;
                    if (postfilterassmebly != "")
                    {
                        pfassembly = CargarAssembly(postfilterassmebly);
                    }
                }
                catch (Exception e)
                {
                    //postfilterassmebly = "";
                    throw (e);
                }
            }
        }

        private string postfilterclass = "";
        private System.Type pftype;
        private Interfaces.IPostFilter[] pfclass;
        [WebBrowsable(true),
         Personalizable(true),
         Category("Post Filter"),
         DisplayName("Post Filter Classes"),
         WebDisplayName("Post Filter Classes"),
         Description("Please enter the ClassName of the Classes (separated by comma) in the PostFilter Assembly who implements the IPostFilter interface that will be used to process the XML resultant of the CAML query before parsing it with the XSLT Stylesheet. The Classes will be invoked in the order of appearence.")]
        public string PostFilterClass
        {
            get { return postfilterclass; }
            set
            {
                try
                {
                    postfilterclass = value;
                }
                catch (Exception e)
                {
                    //postfilterclass = "";
                    throw (e);
                }
            }
        }

        private string postfilterparam1 = "";
        [WebBrowsable(true),
         Personalizable(true),
         Category("Post Filter"),
         DisplayName("Custom Parameter 1"),
         WebDisplayName("Custom Parameter 1"),
         Description("Please enter the value of Parameter 1 passed to PostFilter class.")]
        public string PostFilterParam1
        {
            get { return postfilterparam1; }
            set { postfilterparam1 = value; }
        }

        private string postfilterparam2 = "";
        [WebBrowsable(true),
         Personalizable(true),
         Category("Post Filter"),
         DisplayName("Custom Parameter 2"),
         WebDisplayName("Custom Parameter 2"),
         Description("Please enter the value of Parameter 2 passed to PostFilter class.")]
        public string PostFilterParam2
        {
            get { return postfilterparam2; }
            set { postfilterparam2 = value; }
        }

        private string postfilterparam3 = "";
        [WebBrowsable(true),
         Personalizable(true),
         Category("Post Filter"),
         DisplayName("Custom Parameter 3"),
         WebDisplayName("Custom Parameter 3"),
         Description("Please enter the value of Parameter 3 passed to PostFilter class.")]
        public string PostFilterParam3
        {
            get { return postfilterparam3; }
            set { postfilterparam3 = value; }
        }

        private string postfilterparam4 = "";
        [WebBrowsable(true),
         Personalizable(true),
         Category("Post Filter"),
         DisplayName("Custom Parameter 4"),
         WebDisplayName("Custom Parameter 4"),
         Description("Please enter the value of Parameter 4 passed to PostFilter class.")]
        public string PostFilterParam4
        {
            get { return postfilterparam4; }
            set { postfilterparam4 = value; }
        }
       
        private string html = "";
        public string Html
        {
            get { return html; }
        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            System.Web.UI.HtmlControls.HtmlInputHidden hi = new System.Web.UI.HtmlControls.HtmlInputHidden();
            hi.Name = "SelectedElement";
            hi.ID = "SelectedElement";
            this.Controls.Add(hi);
            System.Web.UI.WebControls.LinkButton bu = new System.Web.UI.WebControls.LinkButton();
            bu.Style.Add("display", "none");
            bu.OnClientClick = "alert('si'); this.form['"+ hi.UniqueID +"'].value='vamos vamos';";
            bu.Click += new EventHandler(bu_Click);
            this.Controls.Add(bu);
        }
        private void bu_Click(object sender, EventArgs e)
        {
            System.Web.HttpContext.Current.Response.Write("siiii#" + ((System.Web.UI.HtmlControls.HtmlInputHidden)this.Controls[0]).Value + "#");
        }
        protected override void Render(HtmlTextWriter writer)
        {
            base.Render(writer);
            bool doRender = false;
            if (String.IsNullOrEmpty(xmlstring) || String.IsNullOrEmpty(xmlfile))
            {
                if (String.IsNullOrEmpty(caml) || String.IsNullOrEmpty(camlfile))
                {
                    if (!String.IsNullOrEmpty(camldoc.InnerXml))
                    {
                        if (String.IsNullOrEmpty(xsl) || String.IsNullOrEmpty(xslfile))
                        {
                            doRender = true;
                        }
                        else
                        {
                            writer.Write("You cannot use the XSL Sheet (file) parameter alongside the XSL Sheet (plain text) parameter. You must clear one of them.");
                        }
                    }
                    else
                    {
                        writer.Write("Fill the CAML (plain text) parameter with the appropiate CAML query or fill the CAML (file) parameter with a URL for a file containing an appropiate CAML query.");
                    }
                }
                else
                {
                    writer.Write("You cannot use the CAML (file) parameter alongside the CAML (plain text) parameter. You must clear one of them.");
                }
            }
            else
            {
                writer.Write("You cannot use the Custom XML (file) parameter alongside the Custom XML (plain text) parameter. You must clear one of them.");
            }

            if (doRender)
            {
                try
                {
                    SPSite site;

                    if (website == "")
                    {
                        site = SPContext.Current.Site;
                    }
                    else
                    {
                        if (website.StartsWith("$"))
                        {
                            if (System.Web.HttpContext.Current.Request.QueryString[website.Replace("$", "")] != null)
                            {
                                site = new SPSite(ParseQueryString(website, System.Web.HttpContext.Current.Request.QueryString));
                            }
                            else
                            {
                                site = SPContext.Current.Site;
                            }
                        }
                        else
                        {
                            if (website.StartsWith("http://"))
                            {
                                site = new SPSite(website);
                            }
                            else if (website.StartsWith("/"))
                            {
                                site = new SPSite("http://" + System.Web.HttpContext.Current.Request.Url.Host + ":" + System.Web.HttpContext.Current.Request.Url.Port + website);
                            }
                            else
                            {
                                string fullwebsite = "http://" + System.Web.HttpContext.Current.Request.Url.Host + ":" + System.Web.HttpContext.Current.Request.Url.Port;
                                for (int iter = 0; iter < System.Web.HttpContext.Current.Request.Url.Segments.Length - 1; iter++)
                                {
                                    fullwebsite += System.Web.HttpContext.Current.Request.Url.Segments[iter];
                                }
                                site = new SPSite(fullwebsite + website);
                            }
                        }
                    }
                    SPWeb web = site.OpenWeb();
                    XmlDocument queryDoc = new XmlDocument();
                    Hashtable parameters = BuildParameters(System.Web.HttpContext.Current.Request.QueryString);
                    if (preprocessclass != "")
                    {
                        LoadPreProcessClass();
                        for (int iter = 0; iter < ppclass.Length; iter++)
                        {
                            if (ppclass[iter] != null)
                            {
                                ppclass[iter].Init(preprocessparam1, preprocessparam2, preprocessparam3, preprocessparam4);
                                parameters = ppclass[iter].Process(ref camldoc, parameters);
                            }
                        }
                    }
                    ParseQueryString(ref camldoc, System.Web.HttpContext.Current.Request.QueryString);
                    ParseParameters(ref camldoc, parameters);
                    extraxmldoc.InnerXml = "<ExtraXML></ExtraXML>";
                    if (camldoc.SelectSingleNode("/Multiple") == null)
                    {
                        RunQuery(web, camldoc.SelectSingleNode("/Caml"), dsResults);
                    }
                    else
                    {
                        foreach (XmlNode nodo in camldoc.SelectNodes("/Multiple/Caml"))
                        {
                            RunQuery(web, nodo, dsResults);
                        }
                    }
                    if (postfilterclass != "")
                    {
                        LoadPostFilterClass();
                        for (int iter = 0; iter < pfclass.Length; iter++)
                        {
                            if (pfclass[iter] != null)
                            {
                                pfclass[iter].Init(parameters, postfilterparam1, postfilterparam2, postfilterparam3, postfilterparam4);
                                dsResults = pfclass[iter].Filter(dsResults);
                            }
                        }
                    }
                    xmlres.InnerXml = dsResults.GetXml();
                    if (xmlstring != "" || xmlfile != "")
                    {
                        xmlres.SelectSingleNode("/NewDataSet").AppendChild(xmlres.CreateElement("CustomXML"));
                        xmlres.SelectSingleNode("/NewDataSet/CustomXML").InnerXml = xmldoc.InnerXml;
                    }
                    xmlres.SelectSingleNode("/NewDataSet").AppendChild(xmlres.ImportNode(extraxmldoc.FirstChild,true));
                    if (passparameters)
                    {
                        XmlNode paraminfo = extraxmldoc.SelectSingleNode("/ExtraXML").AppendChild(extraxmldoc.CreateElement("ParamInfo"));
                        XmlNode param;
                        foreach (string llave in parameters.Keys) {
                            param = paraminfo.AppendChild(extraxmldoc.CreateElement(llave));
                            param.InnerText = parameters[llave].ToString();
                        }
                    }
                    if (xsl != "" || xslfile != "")
                    {

                        if (System.Web.HttpContext.Current.Request.QueryString["overridesxsl"] != null)
                        {
                            xsldoc.Load(System.Web.HttpContext.Current.Request.QueryString["overridesxsl"].ToString());
                        }
                        System.IO.StringWriter htmlwriter = new System.IO.StringWriter();
                        xsldoc.Transform(xmlres.CreateNavigator(), new System.Xml.Xsl.XsltArgumentList(), htmlwriter);
                        html = htmlwriter.ToString();
                        if (System.Web.HttpContext.Current.Request.QueryString["iframed"] != null)
                        {
                            System.Random rnd = new Random();
                            int sessionid = rnd.Next(10000, 99999);
                            System.IO.TextWriter htmlwrt = System.IO.File.CreateText("C:\\WINDOWS\\Temp\\html" + sessionid + ".html");
                            htmlwrt.Write(html);
                            htmlwrt.Close();
                            htmlwrt.Dispose();
                            htmlwrt = null;
                            string iframewidth = "";
                            string iframeheight = "";
                            if (System.Web.HttpContext.Current.Request.QueryString["iframewidth"] != null)
                            {
                                iframewidth = "width=\"" + System.Web.HttpContext.Current.Request.QueryString["iframewidth"].ToString() + "\"";
                            }
                            if (System.Web.HttpContext.Current.Request.QueryString["iframeheight"] != null)
                            {
                                iframeheight = "height=\"" + System.Web.HttpContext.Current.Request.QueryString["iframewidth"].ToString() + "\"";
                            }
                            html = "<iframe src=\"" + System.Web.HttpContext.Current.Request.QueryString["iframed"] + "?sessionid=" + sessionid + "\" " + iframewidth + " " + iframeheight + "></iframe>";
                            if (System.Web.HttpContext.Current.Request.QueryString["iframeback"] != null)
                            {
                                html += "<p align=\"center\">";
                                html += "<img src=\"/_layouts/images/rect.gif\"/>&nbsp;<a class=\"ms-addnew\" href=\"javascript:history.back();\">Volver atr&aacute;s</a>";
                                html += "</p>";
                            }
                        }
                        htmlwriter.Close();
                        htmlwriter.Dispose();
                        htmlwriter = null;
                    }
                    else
                    {
                        html = xmlres.InnerXml;
                    }
                    if (debug)
                    {
                        try
                        {
                            html += "<!--";
                            html += "CAMLDOC.XML";
                            html += camldoc.OuterXml;
                            html += "XMLRES.XML";
                            html += xmlres.OuterXml;
                            html += "-->";
                        }
                        catch (Exception e)
                        {
                            html += e.Message + e.StackTrace;
                            html += "-->";
                        }
                    }
                    writer.Write(html);
                    queryDoc = null;
                }
                catch (Exception e)
                {
                    writer.Write("ERROR: " + e.Message + e.StackTrace);
                }
            }
        }

        private System.Reflection.Assembly CargarAssembly(string assemblyFileOrName)
        {
            if (assemblyFileOrName.EndsWith(".dll",StringComparison.InvariantCultureIgnoreCase)) {
                return System.Reflection.Assembly.LoadFrom(assemblyFileOrName);
            } else {
                return System.Reflection.Assembly.Load(assemblyFileOrName);
            }
        }

        private void LoadXSL(string xslfile)
        {
            xsldoc.Load(LoadXML(xslfile));
        }

        private void LoadCAML(string camlfile)
        {
            camldoc.Load(LoadXML(camlfile));
        }

        private XmlReader LoadXML(string file)
        {
            System.Net.WebClient objClient = new System.Net.WebClient();
            objClient.Credentials= System.Net.CredentialCache.DefaultNetworkCredentials;
            if (!file.StartsWith("http://"))
            {
                Uri dire = new Uri(System.Web.HttpContext.Current.Request.Url,file);
                file = dire.AbsoluteUri;
            }
            XmlReader tempxmlreader = XmlReader.Create(objClient.OpenRead(file));
            objClient.Dispose();
            return tempxmlreader;
        }

        private void RunQuery(SPWeb web, XmlNode nodo, DataSet dsResults)
        {
            XmlAttribute rowlimit;
            XmlNodeList lists = nodo.SelectNodes("Lists/List");
            uint rowlimitnum = 0;

            rowlimit = nodo.Attributes["ROWLIMIT"];
            if (rowlimit != null)
            {
                if (!uint.TryParse(rowlimit.Value.ToString(), out rowlimitnum))
                {
                    rowlimitnum = 0;
                }
            }
            if (rowlimitnum==0) rowlimitnum=2147483647;

            if (lists.Count==1)
            {
                SPQuery spq = new SPQuery();
                SPList list = null;
                XmlAttribute listguid = lists[0].Attributes["ID"];

                if (listguid!=null) {
                    list = web.Lists[new Guid(listguid.Value.ToString())];
                } else {
                    XmlAttribute listname = lists[0].Attributes["NAME"];
                    if (listname != null)
                    {
                        list = web.Lists[listname.Value.ToString()];
                    }
                    else
                    {
                        XmlAttribute listurl = lists[0].Attributes["URL"];
                        if (listurl != null)
                        {
                            list = web.Lists[web.GetFolder(listurl.Value.ToString()).ParentListId];
                        }
                    }
                }
                if (list != null)
                {
                    if (getlistprop == listproperties.SomeProperties || getlistprop == listproperties.FullProperties || getlistprop == listproperties.Schema)
                    {
                        XmlNode listinfo = extraxmldoc.SelectSingleNode("/ExtraXML").AppendChild(extraxmldoc.CreateElement("ListInfo"));
                        listinfo.Attributes.Append(extraxmldoc.CreateAttribute("Id"));
                        listinfo.Attributes["Id"].InnerText = list.ID.ToString();
                        listinfo.Attributes.Append(extraxmldoc.CreateAttribute("Title"));
                        listinfo.Attributes["Title"].InnerText = list.Title;
                        listinfo.Attributes.Append(extraxmldoc.CreateAttribute("Url"));
                        listinfo.Attributes["Url"].InnerText = list.ParentWeb.Url + "/" + list.RootFolder.Url;
                        switch (getlistprop)
                        {
                            case listproperties.FullProperties:
                                listinfo.InnerXml = list.PropertiesXml;
                                break;
                            case listproperties.Schema:
                                listinfo.InnerXml = list.SchemaXml;
                                break;
                        }
                    }
                    spq.Query = nodo.SelectSingleNode("Query").InnerXml;
                    spq.ViewFields = nodo.SelectSingleNode("ViewFields").InnerXml;
                    spq.RowLimit = rowlimitnum;
                    SPListItemCollection slic = list.GetItems(spq);
                    if (slic.Count > 0)
                    {
                        dsResults.Tables.Add(list.GetItems(spq).GetDataTable());
                    }
                    else
                    {
                        dsResults = new DataSet();
                    }
                }
                else
                {
                    dsResults = new DataSet();
                }
            } else if (nodo.Name.ToString().ToUpper()=="SUBSITES") {
                //string imageUrl;
                //string toolTip;
                //Pair webImageData;
                //string destUrl;
                //SPWebCollection webs = Web.GetSubwebsForCurrentUser();
                //foreach (SPWeb webToDisplay in webs)
                //{
                //    webImageData = SPUtility.MapWebToIcon(webToDisplay);
                //    imageUrl = (string)(webImageData.First);
                //    toolTip = SPHttpUtility.HtmlEncode((string)(webImageData.Second));
                //    destUrl = SPHttpUtility.UrlPathEncode(webToDisplay.Url + "/", true);
                //}
            } else {
                SPSiteDataQuery spdq = new SPSiteDataQuery();
                spdq.Query = nodo.SelectSingleNode("Query").InnerXml;
                spdq.ViewFields = nodo.SelectSingleNode("ViewFields").InnerXml;
                spdq.Webs = nodo.SelectSingleNode("Webs").OuterXml;
                spdq.Lists = nodo.SelectSingleNode("Lists").OuterXml;
                spdq.RowLimit = rowlimitnum;
                dsResults.Tables.Add(web.GetSiteData(spdq));
            }
        }

        private void LoadPostFilterClass()
        {
            if (postfilterclass != "" && pfclass == null)
            {
                System.Collections.ArrayList pfclasslist = new ArrayList(postfilterclass.Split(new string[] { "," }, StringSplitOptions.None));
                pfclass = new Interfaces.IPostFilter[pfclasslist.Count];
                foreach (System.Type ty in pfassembly.GetTypes())
                {
                    if (typeof(CAML2HTML.Interfaces.IPostFilter).IsAssignableFrom(ty) && pfclasslist.Contains(ty.Name))
                    {
                        pftype = ty;
                        pfclass[pfclasslist.IndexOf(ty.Name)] = (Interfaces.IPostFilter)System.Activator.CreateInstance(pftype, new object[] { postfilterparam1, postfilterparam2, postfilterparam3, postfilterparam4 });
                    }
                }
            }
        }

        private void LoadPreProcessClass()
        {
            if (preprocessclass != "" && ppclass == null)
            {
                System.Collections.ArrayList ppclasslist = new ArrayList(preprocessclass.Split(new string[] { "," }, StringSplitOptions.None));
                ppclass = new Interfaces.IPreProcess[ppclasslist.Count];
                foreach (System.Type ty in ppassembly.GetTypes())
                {
                    if (typeof(CAML2HTML.Interfaces.IPreProcess).IsAssignableFrom(ty) && ppclasslist.Contains(ty.Name))
                    {
                        pptype = ty;
                        ppclass[ppclasslist.IndexOf(ty.Name)] = (Interfaces.IPreProcess)System.Activator.CreateInstance(pptype, new object[] { preprocessparam1, preprocessparam2, preprocessparam3, preprocessparam4 });
                    }
                }
                
            }
        }

        private void ParseQueryString(ref XmlDocument query, System.Collections.Specialized.NameValueCollection querystring)
        {
            foreach (string key in querystring.AllKeys) {
                query.InnerXml = query.InnerXml.Replace("$" + key, querystring[key]);
            }
        }

        private string ParseQueryString(string query, System.Collections.Specialized.NameValueCollection querystring)
        {
            string output = query;

            foreach (string key in querystring.AllKeys)
            {
                output = output.Replace("$" + key, querystring[key]);
            }

            return output;
        }

        private void ParseParameters(ref XmlDocument query, Hashtable parameters)
        {
            foreach (object key in parameters.Keys)
            {
                query.InnerXml = query.InnerXml.Replace("@" + key.ToString(), parameters[key].ToString());
            }
        }

        private Hashtable BuildParameters(System.Collections.Specialized.NameValueCollection querystring)
        {
            Hashtable output = new Hashtable();

            foreach (string key in querystring.AllKeys)
            {
                output.Add("$" + key, querystring[key]);
            }
            output.Add("now", DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss"));
            output.Add("currentuser", System.Net.CredentialCache.DefaultNetworkCredentials.UserName);
            output.Add("currentuserdomain", System.Net.CredentialCache.DefaultNetworkCredentials.Domain);
            output.Add("preprocessparam1", preprocessparam1);
            output.Add("preprocessparam2", preprocessparam2);
            output.Add("preprocessparam3", preprocessparam3);
            output.Add("preprocessparam4", preprocessparam4);
            if (connectionproviders.Count>0)
            {
                PropertyDescriptor prop;
                for (int iter = 0; iter < connectionproviders.Count; iter++)
                {
                    prop = connectionproviders[iter].Schema;
                    if (prop != null && connectionfields[iter] != null)
                    {
                        output.Add(prop.DisplayName, connectionfields[iter]);
                    }
                }
            }
            return output;
        }

        private void GetRowData(object rowData)
        {
            connectionfields.Add((string)rowData);
        }
      
        protected override void OnPreRender(EventArgs e)
        {
            if (connectionproviders.Count>0)
            {
                for (int iter = 0; iter < connectionproviders.Count; iter++)
                {
                    connectionproviders[iter].GetFieldValue(new FieldCallback(GetRowData));
                }
            }
        }

        private System.Collections.Generic.List<IWebPartField> connectionproviders = new System.Collections.Generic.List<IWebPartField>();
        private System.Collections.Generic.List<string> connectionfields = new System.Collections.Generic.List<string>();
        [ConnectionConsumer("filter", AllowsMultipleConnections = true)]
        public void SetConnectionInterface(IWebPartField provider)
        {
            connectionproviders.Add(provider);
        }

        public class ConnectionBag : IWebPartField
        {
            #region IWebPartField Members

            public void GetFieldValue(FieldCallback callback)
            {
                throw new NotImplementedException();
            }

            public PropertyDescriptor Schema
            {
                get { throw new NotImplementedException(); }
            }

            #endregion
        }

        [ConnectionProvider("result dataset","resultdataset")]
        public DataSet ExportDataSet()
        {
            return dsResults;
        }

        
        [ConnectionProvider("result xml document","resultxmldocument")]
        public XmlDocument ExportXmlDoc()
        {
            return xmlres;
        }

        [ConnectionProvider("selected element", "selectedelement")]
        public IWebPartField ExportSelectedElement()
        {
            return null;
        }

        public override void Dispose()
        {
            base.Dispose();
            //Clearing up memory
            xmlres = null;
            dsResults.Dispose();

            dsResults = null;
        }
    }
}
